package com.ygqh.baby.service.task.impl;

import com.ygqh.baby.ao.DataStatus;
import com.ygqh.baby.model.ProductListRequestParam;
import com.ygqh.baby.model.YgProduct4ListModel;
import com.ygqh.baby.po.YgSearchWords;
import com.ygqh.baby.po.YgTaskTime;
import com.ygqh.baby.service.YgProductService;
import com.ygqh.baby.service.YgSearchWordsService;
import com.ygqh.baby.service.YgTaskTimeService;
import com.ygqh.baby.service.impl.SensitivewordFilter;
import com.ygqh.baby.service.task.YgSearchWordTaskService;
import com.ygqh.baby.solr.YgSolrClient;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ExceptionUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * 搜索词定时检查；
 *
 * @Author: sunshuo
 * @Date: 2019/3/15 14:33
 * @Version: 1.0
 */
@Service
public class YgSearchWordTaskServiceImpl implements YgSearchWordTaskService {

	private final Logger logger = LoggerFactory.getLogger(YgSearchWordTaskServiceImpl.class);

	@Autowired
	private YgSearchWordsService ygSearchWordsService;
	@Autowired
	private YgTaskTimeService ygTaskTimeService;
	@Autowired
	private SensitivewordFilter sensitivewordFilter;
	@Autowired
	private YgProductService ygProductService;

	@Override
	public void checkSearchWord() {
		logger.info("【搜索词检查】任务开始执行。。。。");
		List<YgTaskTime> taskTimeList = ygTaskTimeService.findByName("checkSearchWord");
		YgTaskTime taskTime;
		Date minUpdateTime = null;
		if (CollectionUtils.isEmpty(taskTimeList)) {
			taskTime = new YgTaskTime();
			taskTime.setMothodName("checkSearchWord");
		} else {
			taskTime = taskTimeList.get(0);
			minUpdateTime = DateConvertUtils.addMinute(taskTime.getRunTime(), -2);
		}
		try {
			List<YgSearchWords> searchWordsList = ygSearchWordsService.findByStatus(minUpdateTime, DataStatus.Valid, DataStatus.Disable);
			logger.info("【搜索词检查】searchWordsList size ----->> " + (CollectionUtils.isEmpty(searchWordsList) ? 0 : searchWordsList.size()));
			if (CollectionUtils.isNotEmpty(searchWordsList)) {
				checkSearchWord(searchWordsList);
			}
			taskTime.setRemark("【搜索词检查】执行成功");
		} catch (Exception e) {
			taskTime.setRemark("【搜索词检查】执行失败，" + ExceptionUtil.getExceptionMsg(e));
			logger.error("【搜索词检查】执行失败，" + e.getMessage(), e);
		}
		taskTime.setRunTime(new Date());
		ygTaskTimeService.saveOrUpdate(taskTime);
		logger.info("【搜索词检查】任务执行结束。。。。");
	}

	private void checkSearchWord(List<YgSearchWords> searchWordsList) {
		initHitCount(searchWordsList);
		Iterator<YgSearchWords> iterator = searchWordsList.iterator();
		while (iterator.hasNext()) {
			YgSearchWords searchWords = iterator.next();
			switch (searchWords.getStatus()) {
				case Valid:
					if ((searchWords.getSearchHit() > 0) || (searchWords.getDbHit() > 0)) {
						// 状态未变，过滤
						iterator.remove();
					} else {
						// 有效词已失效，禁用
						searchWords.setStatus(DataStatus.Disable);
					}
					break;
				case Disable:
					int count = sensitivewordFilter.CheckSensitiveWord(searchWords.getWords(), 0, 1);
					if (count > 0) {
						// 敏感词，删除
						searchWords.setStatus(DataStatus.Delete);
					} else if ((searchWords.getSearchHit() > 0) || (searchWords.getDbHit() > 0)) {
						// 禁用词有效，启用
						searchWords.setStatus(DataStatus.Valid);
					} else {
						// 状态未变，过滤
						iterator.remove();
					}
					break;
				default:
					// 异常情况，过滤
					iterator.remove();
			}
		}
		// 批量更新
		ygSearchWordsService.updateStatus(searchWordsList);
	}

	private void initHitCount(List<YgSearchWords> searchWordsList) {
		searchWordsList.forEach(searchWords -> {
			long searchHit = countProductBySearch(searchWords.getWords());
			searchWords.setSearchHit(searchHit);
			if (searchHit == 0) {
				searchWords.setDbHit(countProductByDb(searchWords.getWords()));
			}
		});
	}

	private long countProductByDb(String words) {
		ProductListRequestParam param = new ProductListRequestParam();
		param.setProductName(words);
		List<YgProduct4ListModel> findList = ygProductService.findList(param);
		return CollectionUtils.isEmpty(findList) ? 0 : findList.size();
	}

	private long countProductBySearch(String words) {
		SolrClient solrClient = YgSolrClient.INSTANCE.getSolrClient();
		SolrQuery query = new SolrQuery();
		StringBuilder sb = new StringBuilder();
		sb.append("productName:").append(words)
				.append(" OR ").append("tags:").append(words)
				.append(" OR ").append("basicAttribute:").append(words)
				.append(" OR ").append("sizeNames:").append(words)
				.append(" OR ").append("categoryNames:").append(words);
		query.setQuery(sb.toString());
		query.addFilterQuery("saleStatus:OnSale");
		try {
			QueryResponse response = solrClient.query(query, SolrRequest.METHOD.POST);
			return response.getResults().size();
		} catch (SolrServerException | IOException e) {
			e.printStackTrace();
		}
		return 0;
	}
}
